home *** CD-ROM | disk | FTP | other *** search
-
- /* Copyright (C) 1988, 1989 Herve' Touati, Aquarius Project, UC Berkeley */
-
- /* Copyright Herve' Touati, Aquarius Project, UC Berkeley */
-
- #include <stream.h>
- #include "hash_table.h"
- #include "string_table.h"
-
- inline char* external(int i) {return (char*) i;}
- inline int internal(char* s) {return (int) s;}
-
-
-
- char* StringTable::save_string_copy(char* s)
- {
- extern int strcpy(char*,char*);
- extern int strlen(char*);
- int len = strlen(s) + 1;
- char* new_str = new_string(len);
- strcpy(new_str, s);
- return new_str;
- }
-
- StringTable::StringTable(int string_size, int hash_size) : (hash_size)
- {
- string_space_size = string_size;
- alloc_string_space();
- }
-
- void StringTable::alloc_string_space()
- {
- char* malloc(int);
- next_string = malloc(string_space_size * sizeof(char));
- string_space_left = string_space_size;
- if (next_string == 0) {
- cout << "Symbol Table Overflow\n";
- exit(1);
- }
- }
-
- char* StringTable::new_string(int len)
- {
- if (string_space_left < len + 8) {
- string_space_size <<= 1;
- alloc_string_space();
- }
- int residue = ((int) next_string - 4) % 8;
- if (residue != 0) {
- next_string += 8 - residue;
- string_space_left -= 8 - residue;
- }
- char* result = next_string;
- next_string += len;
- string_space_left -= len;
- return result;
- }
-
- unsigned string_hash(char* s)
- {
- register unsigned h;
- register char* p = s;
- for (h = 0; *p != '\0'; p++)
- h += *p;
- return h;
- }
-
- extern int strcmp(char*,char*);
- inline unsigned string_equal(char* a, char* b)
- {
- return (strcmp(a, b)) ? 0 : 1;
- }
-
- void StringTable::reenter_old_data(int old_size, HashTableEntry** old_table)
- {
- register HashTableEntry** c;
- for (int i = 0; i < old_size; i++) {
- c = &old_table[i];
- while (*c != 0) {
- reintern((*c)->key, (*c)->value);
- c = &((*c)->next);
- }
- }
- }
-
- void StringTable::rehash()
- {
- void free(char*);
- char* old_alloc_area = alloc_area;
- HashTableEntry** old_table = table;
- int old_size = size;
- size <<= 1;
- allocate();
- reenter_old_data(old_size, old_table);
- free(old_alloc_area);
- }
-
- void StringTable::reintern(int key, int value)
- {
- unsigned h = string_hash(external(key));
- HashTableEntry** c = &table[h % size];
- while (*c != 0)
- c = &((*c)->next);
- if ((*c = new_cell()) == 0) {
- cerr << "Error in rehashing\n";
- exit(1);
- }
- (*c)->next = 0;
- (*c)->key = key;
- (*c)->value = value;
- }
-
- int StringTable::intern(char* s)
- {
- unsigned h = string_hash(s);
- HashTableEntry** c = &table[h % size];
- while (*c != 0 && ! string_equal(external((*c)->key), s))
- c = &((*c)->next);
- if (*c == 0) {
- if ((*c = new_cell()) == 0) {
- rehash();
- return intern(s);
- }
- (*c)->next = 0;
- (*c)->value = -1;
- (*c)->key = internal(save_string_copy(s));
- }
- return (*c)->key;
- }
-
- void StringTable::print()
- {
- reset();
- HashTableEntry* e;
- while (e = next())
- printf("\"%s\" %d %d\n",
- external(e->key),
- e->key,
- string_hash(external(e->key)) % size);
- }
-
- static int compute_arity(char* s)
- {
- int atoi(const char*);
- char* rindex(char*, char);
- s = rindex(s, '/');
- return (s == 0) ? 0 : atoi(s + 1);
- }
-
- int StringTable::get_arity(int name)
- {
- int arity = arity_table.get(name);
- if (arity_table.status == HASH_MISS) {
- arity = compute_arity(external(name));
- arity_table.bind(name, arity);
- }
- return arity;
- }
-
- static int check_length(char* s, int limit)
- {
- extern int strlen(char*);
- int len = strlen(s) + 1;
- if (len > limit) {
- cout << "string longer than buffer size: internal limit\n";
- exit(1);
- }
- return len;
- }
-
- int StringTable::atom_to_functor(int atom, int arity)
- {
- static char buffer[256];
- extern int strlen(char*);
- int len = check_length(external(atom), 256);
- extern int sprintf(char*, const char*, ...);
- sprintf(buffer, "%s/%d", external(atom), arity);
- int result = intern(buffer);
- arity_table.bind(result, arity);
- return result;
- }
-
- int StringTable::functor_to_atom(int functor)
- {
- char buffer[256];
- extern int strlen(char*);
- int len = check_length(external(functor), 256);
- extern int strcpy(char*, char*);
- strcpy(buffer, external(functor));
- extern char* rindex(char*, char);
- char* p = rindex(buffer, '/');
- if (p != 0) *p = '\0';
- int result = intern(buffer);
- return result;
- }
-
-